#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>


void handler(int signo)
{
  pid_t id;
  // while循环是为多个子进程退出时，都发送SIGCHLD信号时，能够准确对每个子进程释放空间
  // WNOHANG非阻塞等待,是为了存在多个子进程，只有一部分子进程退出时，非阻塞等待可以保证剩余的子进程和主进程都能够正常运行，等剩余进程退出时，再进行waitpid释放
  // 阻塞等待表示父进程什么都不做，一直再等待子进程退出
  // 非阻塞等待表示父进程轮询的方式检测子进程是否退出
  while((id = waitpid(-1, NULL, WNOHANG)) > 0)
  {
    printf("child process exit success\n");
  }
  printf("signo->%d, child_pid->%d, parent_pid->%d\n", signo, id, getpid());
}

int main()
{
  signal(SIGCHLD, handler);
  // 通过手动捕获子进程的SIGCHLD信号，并且忽略信号，当子进程退出时，自动释放僵尸进程
  // 这样可以不用waitpid来解决子进程退出时，子进程成为僵尸进程出现内存泄漏问题
  // signal(SIGCHLD, SIG_IGN);
  if(fork() == 0)
  {
    printf("I am child, pid->%d\n", getpid());
    sleep(5);
    exit(2);
  }

  while(1)
  {
    printf("parent process doing anything\n");
    sleep(1);
  }
  return 0;
}
